package org.idea.qiyu.framework.threadpool.dynamic.executor;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 原生定义的线程池
 *
 * @Author linhao
 * @Date created in 10:39 上午 2021/10/26
 */
@Slf4j
public class QiyuExecutor extends ThreadPoolExecutor {

    private final ThreadLocal<Map<String,Object>> startTime = new ThreadLocal<>();

    public QiyuExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    public QiyuExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
    }

    public QiyuExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
    }

    public QiyuExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    @Override
    public void execute(Runnable command) {
        super.execute(command);
    }

    @Override
    public void shutdown() {
        super.shutdown();
    }

    @Override
    public List<Runnable> shutdownNow() {
        return super.shutdownNow();
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        String threadName = Thread.currentThread().getName();
        Map<String,Object> threadInfoMap = new HashMap<>();
        threadInfoMap.put("threadName",threadName);
        threadInfoMap.put("beginTime",System.currentTimeMillis());
        startTime.set(threadInfoMap);
        super.beforeExecute(t, r);
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        long endTime = System.currentTimeMillis();
        Map<String,Object> threadInfoMap = startTime.get();
        long executeTime = endTime - (long) threadInfoMap.get("beginTime");
        log.info("Thread {}: ExecuteTime {}", threadInfoMap.get("threadName"), executeTime);
    }

    /**
     * 打印线程池各项参数指标
     */
    public void getTaskInfo(){
        log.info("coreSize: {}, maxSize: {}, activeCount:{},blockQueueSize:{}",super.getCorePoolSize(),super.getMaximumPoolSize(),super.getActiveCount(),super.getQueue().size());
    }

    /**
     * 获取队列数目
     *
     * @return
     */
    public int getQueueSize(){
        return super.getQueue().size();
    }

    @Override
    public long getTaskCount() {
        return super.getTaskCount();
    }

    @Override
    public long getCompletedTaskCount() {
        return super.getCompletedTaskCount();
    }
}
